<?php

class RpcApi extends ApiBase {
	public $handle;

	public function __construct() {
		parent::__construct();
		$this->handle = curl_multi_init();
	}

	public function callBack(array $urls, $callback) {
		foreach ($urls as $url) {
			$ch = curl_init($url);
			curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
			curl_multi_add_handle($this->handle, $ch);
		}

		$active = null;
		do {
			$mrc = curl_multi_exec($this->handle, $active);
		} while ($mrc == CURLM_CALL_MULTI_PERFORM);

		while ($active && $mrc == CURLM_OK) {
			if (curl_multi_select($this->handle) != -1) {
				do {
					$mrc = curl_multi_exec($this->handle, $active);
					if ($state = curl_multi_info_read($this->handle)) {
						$info = curl_getinfo($state['handle']);
						$callback(curl_multi_getcontent($state['handle']), $info);
						curl_multi_remove_handle($this->handle, $state['handle']);
					}
				} while ($mrc == CURLM_CALL_MULTI_PERFORM);
			}
		}
	}

	public function callGet(array $urls) {
		foreach ($urls as $url) {
			$ch = curl_init($url);
			curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
			curl_multi_add_handle($this->handle, $ch);
		}

		$active = null;
		do {
			$mrc = curl_multi_exec($this->handle, $active);
		} while ($mrc == CURLM_CALL_MULTI_PERFORM);

		$rs = array();
		while ($active && $mrc == CURLM_OK) {
			if (curl_multi_select($this->handle) != -1) {
				do {
					$mrc = curl_multi_exec($this->handle, $active);
					if ($state = curl_multi_info_read($this->handle)) {
						$url = curl_getinfo($state['handle'], CURLINFO_EFFECTIVE_URL);
						$rs[$url] = curl_multi_getcontent($state['handle']);
						curl_multi_remove_handle($this->handle, $state['handle']);
					}
				} while ($mrc == CURLM_CALL_MULTI_PERFORM);
			}
		}

		return $rs;
	}

	public function callPost(array $urlDs) {
		$stime = microtime(true);
		$sid = $urlDs[0]['data']['sourceId'];
		if (count($urlDs) == 1) {
			$url = $urlDs[0]['url'];
			$data = $urlDs[0]['data'];

			$ch = curl_init($url);
			curl_setopt($ch, CURLOPT_HEADER, 0);
			curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
			curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 6.1; rv:11.0) Gecko/20100101 Firefox/11.0');
			curl_setopt($ch, CURLOPT_POST, 1);
			curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));

			$rs[$url] = curl_exec($ch);

			$xx[$sid] = curl_getinfo($ch);
			n_logSave("curlxxx.log", var_export($xx, true));

			curl_close($ch);

			$nb = (microtime(true) - $stime)*1000;
			n_logSave("multi.log", var_export("$sid : $nb",true));

			return $rs;
		}

		$conn = array();
		$rs = array();
		foreach ($urlDs as $urlD) {
			$url = $urlD['url'];
			$data = $urlD['data'];

			$ch = curl_init($url);
			// curl_setopt($ch, CURLOPT_NOSIGNAL,1);
			// curl_setopt($ch, CURLOPT_CONNECTTIMEOUT_MS, 200);
			curl_setopt($ch, CURLOPT_HEADER, 0);
			curl_setopt($ch, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
			curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
			curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 6.1; rv:11.0) Gecko/20100101 Firefox/11.0');
			curl_setopt($ch, CURLOPT_POST, 1);
			curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));
			curl_multi_add_handle($this->handle, $ch);

			$conn[$url] = $ch;
		}

		$active = null;
		do {
			$mrc = curl_multi_exec($this->handle, $active);
		} while ($mrc == CURLM_CALL_MULTI_PERFORM);

		while ($active && $mrc == CURLM_OK) {
			if (curl_multi_select($this->handle) != -1) {
				do {
					$mrc = curl_multi_exec($this->handle, $active);
					$infoerr = curl_multi_info_read($this->handle);
					if (0 != $infoerr['result'])
						n_logSave('readmulit.log', var_export($infoerr, true));

					/*if ($state = curl_multi_info_read($this->handle)) {
						$url = curl_getinfo($state['handle'], CURLINFO_EFFECTIVE_URL);
						$rs[$url] = curl_multi_getcontent($state['handle']);

						$bb[$sid] = curl_strerror($state['result']);
						if ($bb[$sid] != ''){
							$bb['url'] = $url;
							$bb['time'] = date("Y-m-d H:i:s");
							$bb['retval'] = $rs[$url];
							n_logSave("xxerrorCurl.log", var_export($bb, true));
						}
						curl_multi_remove_handle($this->handle, $state['handle']);
					}*/
				} while ($mrc == CURLM_CALL_MULTI_PERFORM);
			}
		}

		foreach ($conn as $url => $ch) {
			$rs[$url] = curl_multi_getcontent($ch);

			$bb[$sid] = curl_error($ch);
			if ($bb[$sid] != '')
			        n_logSave('xxerrorCurl.log', var_export($bb, true));

			$fuckc[$sid] = curl_getinfo($ch);
			n_logSave('curlxxx.log', var_export($fuckc, true));

			curl_multi_remove_handle($this->handle, $ch);
		}
		curl_multi_close($this->handle);

		$vb[$sid] = $rs;
		n_logSave('rsofcurl.log', var_export($vb, true));
		return $rs;
	}

	public function __destruct() {
		// curl_multi_close($this->handle);
	}
}